home *** CD-ROM | disk | FTP | other *** search
- /* External panelize
- Copyright (C) 1995 The Free Software Foundation
-
- Written by: 1995 Janne Kukonlehto
- 1995 Jakub Jelinek
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include <config.h>
- #ifdef HAVE_UNISTD_H
- # include <unistd.h>
- #endif
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h> /* For malloc() */
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/stat.h>
- #include <grp.h>
- #include <pwd.h>
- #include "tty.h"
- #include "mad.h"
- #include "util.h" /* Needed for the externs */
- #include "win.h"
- #include "color.h"
- #include "dlg.h"
- #include "widget.h"
- #include "dialog.h" /* For do_refresh() */
- #include "setup.h" /* For profile_bname */
- #include "profile.h" /* Load/save directories panelize */
- #include "fs.h"
-
- /* Needed for the extern declarations of integer parameters */
- #define DIR_H_INCLUDE_HANDLE_DIRENT
- #include "dir.h"
- #include "panel.h" /* Needed for the externs */
- #include "file.h"
- #include "main.h"
- #include "global.h"
-
- void do_external_panelize (char *command);
-
- #define UX 5
- #define UY 2
-
- #define BX 5
- #define BY 18
-
- #define BUTTONS 4
- #define LABELS 3
- #define B_ADD B_USER
- #define B_REMOVE B_USER + 1
-
- static WListbox *l_panelize;
-
- static Dlg_head *panelize_dlg;
-
- static WInput *pname;
-
- static char *panelize_section = "Panelize";
-
- static int last_listitem;
-
- struct {
- int ret_cmd, y, x;
- char *text;
- int hkey, hpos;
- } panelize_but[BUTTONS] = {
- { B_CANCEL, 0, 53, "[ Cancel ]", 'c', 2, },
- { B_ADD, 0, 28, "[ Add new ]", 'a', 2, },
- { B_REMOVE, 0, 16, "[ Remove ]", 'r', 2, },
- { B_ENTER, 0, 0, "[[ Panelize ]]", 'p', 5, },
- };
-
- /* Directory panelize */
- static struct panelize{
- char *command;
- char *label;
- struct panelize *next;
- } *panelize = NULL;
-
- #ifndef HAVE_X
- static void panelize_refresh (void)
- {
- attrset (REVERSE_COLOR);
- dlg_erase (panelize_dlg);
-
- draw_box (panelize_dlg, 1, 2, 20, 70);
- draw_box (panelize_dlg, UY, UX, 12, 63);
-
- attrset (COLOR_HOT_NORMAL);
- dlg_move (panelize_dlg, 1, (72 - 19) / 2);
- addstr (" External panelize ");
- }
- #endif
-
- static INLINE void update_command ()
- {
- if (l_panelize->pos != last_listitem) {
- last_listitem = l_panelize->pos;
- assign_text (pname,
- ((struct panelize *) l_panelize->current->data)->command);
- pname->point = 0;
- update_input (pname);
- }
- }
-
- static int panelize_callback (Dlg_head * h, int Par, int Msg)
- {
- switch (Msg) {
- #ifndef HAVE_X
- case DLG_DRAW:
- panelize_refresh ();
- break;
- #endif
-
- case DLG_POST_KEY:
- /* fall */
- case DLG_INIT:
- attrset (MENU_ENTRY_COLOR);
- update_command ();
- break;
- }
- return 0;
- }
-
- static int l_call (void *data)
- {
- return 1;
- }
-
- static void init_panelize (void)
- {
- int i;
- struct panelize *current = panelize;
-
- last_listitem = 0;
-
- do_refresh ();
-
- panelize_dlg = create_dlg (0, 0, 22, 74, dialog_colors,
- panelize_callback, "[External panelize]", "Panelize",
- DLG_CENTER);
- x_set_dialog_title (panelize_dlg, "External panelize");
-
- #define XTRACT(i) BY+panelize_but[i].y, BX+panelize_but[i].x, panelize_but[i].ret_cmd, panelize_but[i].text, panelize_but[i].hkey, panelize_but[i].hpos, 0, 0
-
- for (i = 0; i < BUTTONS; i++)
- add_widgetl (panelize_dlg, button_new (XTRACT (i)), (i == BUTTONS - 1) ?
- XV_WLAY_CENTERROW : XV_WLAY_RIGHTOF);
-
- pname = input_new (UY+14, UX, INPUT_COLOR, 63, "");
- add_widgetl (panelize_dlg, pname, XV_WLAY_RIGHTOF);
-
- add_widgetl (panelize_dlg, label_new (UY+13, UX, "Command"), XV_WLAY_NEXTROW);
-
- /* get new listbox */
- l_panelize = listbox_new (UY + 1, UX + 1, 61, 10, 0, l_call);
-
- while (current){
- listbox_add_item (l_panelize, 0, 0, current->label, current);
- current = current->next;
- }
-
- /* add listbox to the dialogs */
- add_widgetl (panelize_dlg, l_panelize, XV_WLAY_EXTENDWIDTH);
-
- listbox_select_entry (l_panelize,
- listbox_search_text (l_panelize, "Other command"));
- }
-
- static void panelize_done (void)
- {
- destroy_dlg (panelize_dlg);
- repaint_screen ();
- }
-
- static void add2panelize (char *label, char *command)
- {
- struct panelize *current, *old;
-
- old = NULL;
- current = panelize;
- while (current && strcmp (current->label, label) <= 0){
- old = current;
- current = current->next;
- }
-
- if (old == NULL){
- panelize = malloc (sizeof (struct panelize));
- panelize->label = label;
- panelize->command = command;
- panelize->next = current;
- } else {
- struct panelize *new;
- new = malloc (sizeof (struct panelize));
- new->label = label;
- new->command = command;
- old->next = new;
- new->next = current;
- }
- }
-
- void add2panelize_cmd (void)
- {
- char *label;
-
- if (pname->buffer && (*pname->buffer)) {
- label = input_dialog (" Add to external panelize ", "Unnamed find",
- "");
- if (!label)
- return;
- if (!*label) {
- free (label);
- return;
- }
-
- add2panelize (label, strdup(pname->buffer));
- }
- }
-
- static void remove_from_panelize (struct panelize *entry)
- {
- if (entry == panelize){
- panelize = panelize->next;
- } else {
- struct panelize *current = panelize;
- while (current && current->next != entry)
- current = current->next;
- if (current){
- current->next = entry->next;
- }
- }
-
- /* FIXME: Commented out because freeing seems to cause corruption
- after some add and remove operations */
- /*free (entry->label);
- free (entry->command);
- free (entry);*/
- }
-
- void external_panelize (void)
- {
- char *target = NULL;
-
- init_panelize ();
-
- /* display file info */
- attrset (SELECTED_COLOR);
-
- run_dlg (panelize_dlg);
-
- switch (panelize_dlg->ret_value) {
- case B_CANCEL:
- break;
-
- case B_ADD:
- add2panelize_cmd ();
- break;
-
- case B_REMOVE:
- remove_from_panelize (l_panelize->current->data);
- break;
-
- case B_ENTER:
- target = pname->buffer;
- if (target != NULL && *target) {
- char *cmd = strdup (target);
- destroy_dlg (panelize_dlg);
- do_external_panelize (cmd);
- free (cmd);
- repaint_screen ();
- return;
- }
- break;
- }
-
- panelize_done ();
- }
-
- void load_panelize (void)
- {
- void *profile_keys;
- char *key, *value;
-
- profile_keys = profile_init_iterator (panelize_section, profile_name);
-
- add2panelize (strdup ("Other command"), strdup (""));
-
- if (!profile_keys){
- add2panelize (strdup ("Find rejects after patching"), strdup ("find . -name \\*.rej -print"));
- add2panelize (strdup ("Find *.orig after patching"), strdup ("find . -name \\*.orig -print"));
- add2panelize (strdup ("Find SUID and SGID programs"), strdup ("find . \\( \\( -perm -04000 -a -perm +011 \\) -o \\( -perm -02000 -a -perm +01 \\) \\) -print"));
- return;
- }
-
- while (profile_keys){
- profile_keys = profile_iterator_next (profile_keys, &key, &value);
- add2panelize (strdup (key), strdup (value));
- }
- }
-
- void save_panelize (void)
- {
- struct panelize *current = panelize;
-
- profile_clean_section (panelize_section, profile_name);
- for (;current; current = current->next){
- if (strcmp (current->label, "Other command"))
- WritePrivateProfileString (panelize_section,
- current->label,
- current->command,
- profile_name);
- }
- sync_profiles ();
- }
-
- void done_panelize (void)
- {
- struct panelize *current = panelize;
- struct panelize *next;
-
- for (; current; current = next){
- next = current->next;
- free (current->label);
- free (current->command);
- free (current);
- }
- }
-
- struct spaced_dirent {
- struct dirent dp;
- #ifdef NEED_EXTRA_DIRENT_BUFFER
- char extra_buffer [MC_MAXPATHLEN];
- #endif
- };
-
- void do_external_panelize (char *command)
- {
- struct spaced_dirent dp;
- int status, link_to_dir, stalled_link;
- int next_free = 0;
- struct stat buf;
- dir_list *list = &cpanel->dir;
- char line [MC_MAXPATHLEN];
- FILE *external;
-
- open_error_pipe ();
- external = popen (command, "r");
- if (!external){
- close_error_pipe (1, "Cannot invoke command.");
- return;
- }
- clean_dir (list, cpanel->count);
-
- /* Clear the counters */
- cpanel->total = cpanel->dirs_marked = cpanel->marked = 0;
- while (1) {
- clearerr(external);
- if (fgets (line, MC_MAXPATHLEN, external) == NULL)
- if (ferror(external) && errno == EINTR)
- continue;
- else
- break;
- if (line[strlen(line)-1] == '\n')
- line[strlen(line)-1] = 0;
- if (strlen(line) < 1)
- continue;
- if (line [0] == '.' && line[1] == PATH_SEP)
- strcpy (dp.dp.d_name, line + 2);
- else
- strcpy (dp.dp.d_name, line);
- #if !defined(HAVE_DIRENT_H) && !defined(_POSIX_VERSION)
- NLENGTH (&dp.dp) = strlen (dp.dp.d_name);
- #endif
- status = handle_dirent (list, NULL, &dp.dp, &buf, next_free, &link_to_dir,
- &stalled_link);
- if (status == 0)
- continue;
- if (status == -1)
- break;
- list->list [next_free].fnamelen = NLENGTH (&(dp.dp));
- list->list [next_free].fname = strdup (dp.dp.d_name);
- list->list [next_free].cache = NULL;
- file_mark (cpanel, next_free, 0);
- list->list [next_free].f.link_to_dir = link_to_dir;
- list->list [next_free].f.stalled_link = stalled_link;
- list->list [next_free].buf = buf;
- next_free++;
- if (!(next_free & 32))
- rotate_dash ();
- }
- if (next_free){
- cpanel->count = next_free;
- cpanel->is_panelized = 1;
- if (list->list [0].fname [0] == PATH_SEP){
- strcpy (cpanel->cwd, PATH_SEP_STR);
- chdir (PATH_SEP_STR);
- }
- } else {
- do_load_dir (list, cpanel->sort_type, cpanel->reverse, cpanel->case_sensitive, cpanel->filter);
- cpanel->count = set_zero_dir (list);
- }
- if (pclose (external) < 0)
- message (2, "External panelize", "Pipe close failed");
- close_error_pipe (0, 0);
- try_to_select (cpanel, NULL);
- paint_panel (cpanel);
- }
-